package com.useeinfo.oa.modules.base.biz;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.useeinfo.framework.extend.biz.CrudBiz;
import com.useeinfo.framework.sugar.data.QueryParam;
import com.useeinfo.framework.sugar.data.SelectVO;
import com.useeinfo.framework.sugar.func.excel.ExcelImport;
import com.useeinfo.framework.sugar.func.excel.ExcelImportParam;
import com.useeinfo.framework.sugar.func.excel.ExcelMapImport;
import com.useeinfo.framework.sugar.func.lang.StringUtils;
import com.useeinfo.framework.sugar.tools.Configuration;
import com.useeinfo.framework.sugar.tools.StringConverters;
import com.useeinfo.oa.common.utils.ResultUtil.ResultDto;
import com.useeinfo.oa.common.utils.ResultUtil.ResultUtil;
import com.useeinfo.oa.modules.base.dao.PersonnelDao;
import com.useeinfo.oa.modules.base.entity.*;
import com.useeinfo.oa.modules.base.vo.FacilityVO;
import com.useeinfo.oa.modules.security.biz.OrganizationBiz;
import com.useeinfo.oa.modules.security.biz.SystemUserBiz;
import com.useeinfo.oa.modules.security.entity.SystemUser;
import com.useeinfo.oa.modules.security.start.InstantiationTracingBeanPostProcessor;
import com.useeinfo.oa.modules.security.util.SessionKeyUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @program: YiYouFuPlatform
 * @author: Taogq
 * @createDate: 2018-12-04
 * @createTime: 16:12:33
 */
@Service
public class PersonnelBiz extends CrudBiz<PersonnelDao, Personnel> {
    @Autowired
    private PositionBiz positionBiz;
    @Autowired
    private OrganizationBiz organizationBiz;
    @Autowired
    private AreaBiz areaBiz;
    @Autowired
    private SystemUserBiz systemUserBiz;
    @Autowired
    private EnterprisePersonnelSystemUserBiz enterprisePersonnelSystemUserBiz;
    @Autowired
    private PersonnnelOrganizationBiz personnnelOrganizationBiz;
    @Autowired
    private SystemUserOrganizationBiz systemUserOrganizationBiz;


    /**
     * 人员离职功能
     * @param enterprise
     * @param userId
     * @return
     */
    public JSONObject deleteUser(Enterprise enterprise, String userId) {
        Personnel personnel = dao.findModel(StringConverters.null2Long(userId));
        dao.deleteLogic(personnel);
        JSONObject jsonObject = new JSONObject();

        if (null == personnel) {
            jsonObject.put("result", "false");
            jsonObject.put("message", "该用户不存在，请确认");
            return jsonObject;
        }
        QueryParam query = new QueryParam();
        query.getSqlMap().put("enterpriseId", enterprise.getId().toString());
        query.getSqlMap().put("personnelId", userId);
        List<EnterprisePersonnelSystemUser> enterprisePersonnelSystemUserList = enterprisePersonnelSystemUserBiz.findList(query);
        for (EnterprisePersonnelSystemUser enterprisePersonnelSystemUser : enterprisePersonnelSystemUserList) {
            SystemUser systemUser = enterprisePersonnelSystemUser.getSystemUser();
            //删除中间表对应关系
            if (null != systemUser) {
                Set<Enterprise> enterpriseSet = systemUser.getEnterpriseSet();
                enterpriseSet.remove(enterprise);
                systemUser.setEnterpriseSet(enterpriseSet);
                systemUserBiz.update(systemUser);
            }
            systemUserBiz.deleteLogic(systemUser);//删除对应的用户
            enterprisePersonnelSystemUserBiz.delete(enterprisePersonnelSystemUser.getId());
        }

        String perOrgHql = "select obj from PersonnnelOrganization obj where obj.deleteStatus=false and obj.personnel.id = " + userId + "and obj.organization.enterprise=" + enterprise.getId();
        List<PersonnnelOrganization> personnnelOrganizationList = personnnelOrganizationBiz.hqlExcute(perOrgHql);
        for (PersonnnelOrganization personnnelOrganization : personnnelOrganizationList) {
            personnnelOrganizationBiz.delete(personnnelOrganization.getId());
        }
        String sysOrgHql = "select obj from SystemUserOrganization obj where obj.deleteStatus=false and obj.systemUser.id in ( select o.systemUser.id from EnterprisePersonnelSystemUser o  where o.personnel.id=" + userId + " and o.enterprise.id=" + enterprise.getId() + " ) and obj.organization.enterprise.id=" + enterprise.getId();
        List<SystemUserOrganization> systemUserOrganizationList = systemUserOrganizationBiz.hqlExcute(sysOrgHql);
        for (SystemUserOrganization systemUserOrganization : systemUserOrganizationList) {
            systemUserOrganizationBiz.delete(systemUserOrganization.getId());//删除组织表对应中间表关系
        }

        Set<Enterprise> enterpriseSet = personnel.getEnterpriseSet();
        enterpriseSet.remove(enterprise);
        personnel.setEnterpriseSet(enterpriseSet);
        dao.update(personnel);

        jsonObject.put("result", "true");
        jsonObject.put("message", "成功");
        return jsonObject;
    }

    /**
     * 设为部门管理员
     *
     * @param enterprise
     * @param userId
     * @param flag
     * @return
     */
    public JSONObject designLeader(Enterprise enterprise, String userId, String flag) {
        boolean status = false;
        if ("1".equals(flag)) {
            status = true;
        }
        String perOrgHql = "select obj from PersonnnelOrganization obj where obj.deleteStatus=false and  obj.personnel.id = " + userId + "and obj.organization.enterprise=" + enterprise.getId();
        List<PersonnnelOrganization> personnnelOrganizationList = personnnelOrganizationBiz.hqlExcute(perOrgHql);
        for (PersonnnelOrganization personnnelOrganization : personnnelOrganizationList) {
            personnnelOrganization.setLeader(status);
            personnnelOrganizationBiz.addOrUpdate(personnnelOrganization);
        }
        String sysOrgHql = "select obj from SystemUserOrganization obj where obj.deleteStatus=false and obj.systemUser.id in ( select o.systemUser.id from EnterprisePersonnelSystemUser o  where o.personnel.id=" + userId + " and o.enterprise.id=" + enterprise.getId() + " ) and obj.organization.enterprise.id=" + enterprise.getId();
        List<SystemUserOrganization> systemUserOrganizationList = systemUserOrganizationBiz.hqlExcute(sysOrgHql);
        for (SystemUserOrganization systemUserOrganization : systemUserOrganizationList) {
            systemUserOrganization.setLeader(status);
            systemUserOrganizationBiz.addOrUpdate(systemUserOrganization);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("result", "true");
        jsonObject.put("message", "成功");
        return jsonObject;
        // return ResultUtil.success();
    }

    /**
     * 保存企业信息
     *
     * @param request
     * @param personnel
     * @param positionId
     * @param organizationId
     * @param areaIds
     * @param leader
     * @return
     */
    public ResultDto saveUpdate(HttpServletRequest request, Personnel personnel, String[] positionId, String[] organizationId, String areaIds, String leader) {
        Enterprise enterprise = SessionKeyUtils.getSessionEnterprise(request);
        if (null == enterprise) {
            return ResultUtil.error("当前登录用户的企业信息有误");
        }

        if (checkMobile(personnel.getMobile())) {//验证手机是否已存在--企业管理员或平台管理者
            return ResultUtil.error("该手机号已被企业管理者或平台管理者占用");
        }
        boolean isLeader = false;
        if (StringConverters.null2String(leader).equals("1"))
            isLeader = true;
        Set<Area> areaSet = new HashSet<>();
        Area area;
        if (!StringConverters.null2String(areaIds).equals("")) {
            String[] areaIdStr = areaIds.split(",");
            for (String id : areaIdStr) {
                area = areaBiz.findModel(StringConverters.null2Long(id));
                if (null != area) {
                    areaSet.add(area);
                }
            }
        }
        Position position = null;
        if(positionId.length>0){
             position = positionBiz.findModel(StringConverters.null2Long(positionId[0]));
        }
        Organization organization = null;
        if(organizationId.length>0){
             organization = organizationBiz.findModel(StringConverters.null2Long(organizationId[0]));
        }
        return saveUserMsg(personnel, position, organization, areaSet, enterprise, isLeader);
    }

    /**
     * 保存用户信息，与导入公用
     *
     * @param personnel
     * @param position
     * @param organization
     * @param areaSet
     * @param enterprise
     * @param isLeader
     * @return
     */
    public synchronized ResultDto saveUserMsg(Personnel personnel, Position position, Organization organization, Set<Area> areaSet, Enterprise enterprise, boolean isLeader) {
        Set<Enterprise> enterpriseSet = new HashSet<>();
        Set<Position> positionSet = new HashSet<>();
        SystemUser systemUser = null;
        /**
         * 判断手机号是否存在用户
         */
        QueryParam queryParam = new QueryParam();
        queryParam.getSqlMap().put("mobile", personnel.getMobile());
        List<Personnel> personnelList = dao.findList(queryParam);
        queryParam.getSqlMap().clear();
        queryParam.getSqlMap().put("userAccount", personnel.getMobile());
        List<SystemUser> systemUserList = systemUserBiz.findList(queryParam);
        if (systemUserList.size() > 0) {
            systemUser = systemUserList.get(0);
        }
        Personnel person = null;
        if (CollectionUtils.isNotEmpty(personnelList)) {
            person = personnelList.get(0);
        }

        if (null == person) {//手机号不存在  新增用户
            enterpriseSet.add(enterprise);
            if (null != position) {
                positionSet.add(position);
            }
            personnel.setEnterpriseSet(enterpriseSet);
            personnel.setPositionSet(positionSet);
            personnel.setAreaSet(areaSet);
            dao.add(personnel);

        } else {  //手机号存在  编辑用户

            Personnel personnelEdit = person;
            personnelEdit.setEmail(personnel.getEmail());
            personnelEdit.setEmployeeCode(personnel.getEmployeeCode());
            personnelEdit.setMobile(personnel.getMobile());
            personnelEdit.setSex(personnel.getSex());
            personnelEdit.setName(personnel.getName());
            enterpriseSet = personnelEdit.getEnterpriseSet();
            // enterpriseSet.remove(enterprise);
            if (!enterpriseSet.contains(enterprise)) {
                enterpriseSet.add(enterprise);
            }
            personnelEdit.setEnterpriseSet(enterpriseSet);

            String areaHql = "select obj from Area obj where obj.enterprise.id = " + enterprise.getId() + " and exists( select o from obj.personnelSet o where o.id=" + personnel.getId() + ")";
            List<Area> areaList = areaBiz.hqlExcute(areaHql);
            Set<Area> areas = personnelEdit.getAreaSet();
            areas.removeAll(areaList);
            areas.addAll(areaSet);
            personnelEdit.setAreaSet(areas);
            // personnelEdit.setAreaSet(areaSet);


            String positionHql = "select obj from Position obj where obj.enterprise.id = " + enterprise.getId() + " and exists( select o from obj.personnelSet o where o.id=" + personnel.getId() + ")";
            List<Position> positionList = positionBiz.hqlExcute(positionHql);
            positionSet = personnelEdit.getPositionSet();
            positionSet.removeAll(positionList);
            positionSet.add(position);
            personnelEdit.setPositionSet(positionSet);
            dao.update(personnelEdit);
            personnel = personnelEdit;
        }


        /**
         * 设置普通用户是否是部门管理员以及和组织架构的关系
         */
        String organizePersonHql = "select obj from PersonnnelOrganization obj where obj.deleteStatus=false and  obj.organization.enterprise.id = " + enterprise.getId() + " and obj.personnel.id = " + personnel.getId();
        List<PersonnnelOrganization> personnnelOrganizationList = personnnelOrganizationBiz.hqlExcute(organizePersonHql);
        for (PersonnnelOrganization personnnelOrganization : personnnelOrganizationList) {
            personnnelOrganizationBiz.delete(personnnelOrganization.getId());
        }
        if (null != organization) {
            PersonnnelOrganization personnnelOrganization = new PersonnnelOrganization();
            personnnelOrganization.setOrganization(organization);
            personnnelOrganization.setPersonnel(personnel);
            personnnelOrganization.setLeader(isLeader);
            personnnelOrganizationBiz.addOrUpdate(personnnelOrganization);
        }


        /**
         * 由于hibernate不支持一个集合引用被两个实体引用
         * 需要新建集合信息
         */
        Set<Enterprise> enterprises = new HashSet<>();
        Set<Area> areas = new HashSet<>();
        Set<Organization> organizationSet = new HashSet<>();
        Set<Position> positions = new HashSet<>();
        for (Enterprise ep : personnel.getEnterpriseSet()) {
            enterprises.add(ep);
        }
        for (Area area1 : personnel.getAreaSet()) {
            areas.add(area1);
        }
        for (Position position1 : personnel.getPositionSet()) {
            positions.add(position1);
        }
        /**
         * 创建或者修改系统用户信息
         */
        if (null == systemUser) {
            systemUser = new SystemUser();
            systemUser.setCreateDate(new Date());
            systemUser.setOperationRole("common");
            systemUser.setUserPassword("123456");
            systemUser.setEnterpriseSet(enterprises);
            systemUser.setEmail(personnel.getEmail());
            systemUser.setUserName(personnel.getName());
            systemUser.setMobile(personnel.getMobile());
            systemUser.setUserAccount(personnel.getMobile());
            systemUser.setSex(personnel.getSex());
            systemUser.setAreaSet(areas);
            systemUser.setPositionSet(positions);
            systemUser.setWorkNo(personnel.getEmployeeCode());
            systemUserBiz.addOrUpdate(systemUser);
        } else {
            systemUser.setEnterpriseSet(enterprises);
            systemUser.setEmail(personnel.getEmail());
            systemUser.setUserName(personnel.getName());
            systemUser.setMobile(personnel.getMobile());
            systemUser.setUserAccount(personnel.getMobile());
            systemUser.setSex(personnel.getSex());
            systemUser.setAreaSet(areas);
            systemUser.setPositionSet(positions);
            systemUser.setWorkNo(personnel.getEmployeeCode());
            systemUserBiz.addOrUpdate(systemUser);
        }


        /**
         * 添加系统用户和普通用户之间的关系
         */
        QueryParam query = new QueryParam();
        query.getSqlMap().put("enterpriseId", enterprise.getId().toString());
        query.getSqlMap().put("systemUserId", systemUser.getId().toString());
        query.getSqlMap().put("personnelId", personnel.getId().toString());
        List<EnterprisePersonnelSystemUser> enterprisePersonnelSystemUserList = enterprisePersonnelSystemUserBiz.findList(query);
        if (CollectionUtils.isEmpty(enterprisePersonnelSystemUserList)) {
            EnterprisePersonnelSystemUser enterprisePersonnelSystemUser = new EnterprisePersonnelSystemUser();
            enterprisePersonnelSystemUser.setCreateDate(new Date());
            enterprisePersonnelSystemUser.setEnterprise(enterprise);
            enterprisePersonnelSystemUser.setPersonnel(personnel);
            enterprisePersonnelSystemUser.setSystemUser(systemUser);
            enterprisePersonnelSystemUserBiz.addOrUpdate(enterprisePersonnelSystemUser);
        }

        /**
         * 设置系统用户是否部门管理者以及和组织架构的关系
         */
        String organizeSystemUsetHql = "select obj from SystemUserOrganization obj where obj.deleteStatus=false and obj.organization.enterprise.id = " + enterprise.getId() + " and obj.systemUser.id = " + systemUser.getId();
        List<SystemUserOrganization> systemUserOrganizationList = systemUserOrganizationBiz.hqlExcute(organizeSystemUsetHql);
        for (SystemUserOrganization systemUserOrganization : systemUserOrganizationList) {
            systemUserOrganizationBiz.delete(systemUserOrganization.getId());
        }
        if (null != organization) {
            SystemUserOrganization systemUserOrganization = new SystemUserOrganization();
            systemUserOrganization.setOrganization(organization);
            systemUserOrganization.setSystemUser(systemUser);
            systemUserOrganization.setLeader(isLeader);
            systemUserOrganizationBiz.addOrUpdate(systemUserOrganization);
        }
        return ResultUtil.success();
    }

    /**
     * 验证手机号是否已为企业管理者或平台管理者
     *
     * @param mobile
     * @return
     */
    public boolean checkMobile(String mobile) {
        QueryParam queryParam = new QueryParam();
        queryParam.getSqlMap().put("userAccount", mobile);
        List<SystemUser> systemUserList = systemUserBiz.findList(queryParam);
        if (systemUserList.size() <= 0) {
            return false;
        }
        return ("admin".equals(systemUserList.get(0).getOperationRole()) || "enterprise".equals(systemUserList.get(0).getOperationRole()));
    }


    //private Workbook wb;
    private Sheet sheet;
    private Row row;

    // public ResultDto saveUserMsg(Personnel personnel,Position position,Organization organization,Set<Area>areaSet,Enterprise enterprise,boolean isLeader){
    public synchronized ResultDto importUser(Workbook wb, Enterprise enterprise) {

        if (wb == null) {
            return ResultUtil.error("Workbook对象为空！");
        }
        sheet = wb.getSheetAt(0);
        // 得到总行数
        int rowNum = sheet.getLastRowNum();
        row = sheet.getRow(0);
        int colNum = row.getPhysicalNumberOfCells();
        // 正文内容应该从第二行开始,第一行为表头的标题
        QueryParam queryParam = new QueryParam();
        JSONArray existUser = new JSONArray();
        JSONArray result = new JSONArray();
        JSONObject jsonObject;
        for (int i = 1; i <= rowNum; i++) {
            row = sheet.getRow(i);
            Personnel personnel = new Personnel();
            personnel.setName(StringConverters.null2String(getCellFormatValue(row.getCell(0))));
            personnel.setMobile(StringConverters.null2String(getCellFormatValue(row.getCell(1))));
            personnel.setEmployeeCode(StringConverters.null2String(getCellFormatValue(row.getCell(2))));
            personnel.setSex(StringConverters.null2String(getCellFormatValue(row.getCell(3))).equals("男") ? "男" : "女");
            personnel.setEmail(StringConverters.null2String(getCellFormatValue(row.getCell(4))));

            Position position = new Position();
            String postHql = "select obj from Position obj where obj.deleteStatus=false and obj.enterprise.id=" + enterprise.getId() + " and obj.name = '" + StringConverters.null2String(getCellFormatValue(row.getCell(5))) + "'";
            List<Position> positionList = positionBiz.hqlExcute(postHql);
            if (CollectionUtils.isNotEmpty(positionList)) {
                position = positionList.get(0);
            }
            Organization organization = new Organization();
            String orgHql = "select obj from Organization obj where obj.deleteStatus=false and obj.enterprise.id=" + enterprise.getId() + " and obj.organizationName = '" + StringConverters.null2String(getCellFormatValue(row.getCell(6))) + "'";
            List<Organization> organizationList = organizationBiz.hqlExcute(orgHql);
            if (CollectionUtils.isNotEmpty(organizationList)) {
                organization = organizationList.get(0);
            }

            Set<Area> areaSet = new HashSet<>();
            String[] areaNames = StringConverters.null2String(getCellFormatValue(row.getCell(8))).split("/");
            for (String areaName : areaNames) {
                String areaHql = "select obj from Area obj where obj.deleteStatus=false and obj.enterprise.id=" + enterprise.getId() + " and obj.areaName = '" + areaName + "'";
                List<Area> areaList = areaBiz.hqlExcute(areaHql);
                if (CollectionUtils.isNotEmpty(areaList)) {
                    areaSet.add(areaList.get(0));
                }
            }
            boolean isLeader = StringConverters.null2String(getCellFormatValue(row.getCell(7))).equals("是") ? true : false;

            saveUserMsg(personnel, position, organization, areaSet, enterprise, isLeader);
        }

        return ResultUtil.success();
    }

    /**
     * 根据Cell类型设置数据
     *
     * @param cell
     * @return
     * @author zengwendong
     */
    private Object getCellFormatValue(Cell cell) {
        Object cellvalue = "";
        if (cell != null) {
            // 判断当前Cell的Type
            switch (cell.getCellType()) {
                case Cell.CELL_TYPE_NUMERIC:// 如果当前Cell的Type为NUMERIC
                case Cell.CELL_TYPE_FORMULA: {
                    // 判断当前的cell是否为Date
                    if (DateUtil.isCellDateFormatted(cell)) {
                        // 如果是Date类型则，转化为Data格式
                        // data格式是带时分秒的：2013-7-10 0:00:00
                        // cellvalue = cell.getDateCellValue().toLocaleString();
                        // data格式是不带带时分秒的：2013-7-10
                        Date date = cell.getDateCellValue();
                        cellvalue = date;
                    } else {// 如果是纯数字

                        // 取得当前Cell的数值
                        DecimalFormat dfs = new DecimalFormat("0");

                        cellvalue = dfs.format(cell.getNumericCellValue());
                    }
                    break;
                }
                case Cell.CELL_TYPE_STRING:// 如果当前Cell的Type为STRING
                    // 取得当前的Cell字符串
                    cellvalue = cell.getRichStringCellValue().getString();
                    break;
                default:// 默认的Cell值
                    cellvalue = "";
            }
        } else {
            cellvalue = "";
        }
        return cellvalue;
    }


    /**
     * 根据所给的企业ids查询总人数
     * @param enterpriseIds
     * @return
     */
    public int personCount(String enterpriseIds,String beforeCreateDate) {
        if(StringUtils.isBlank(enterpriseIds)){
            return 0;
        }
        QueryParam queryParam = new QueryParam();
        queryParam.getSqlMap().put("enterpriseIds",enterpriseIds);
        if(StringUtils.isNotBlank(beforeCreateDate)){
            queryParam.getSqlMap().put("beforeCreateDate",beforeCreateDate);
        }
        Long personCount = this.totalRecord(queryParam.getSqlMap());
        if(personCount!=null){
            return personCount.intValue();
        }else{
            return 0;
        }
    }


}
